package com.colortea.action.frontstage.goods;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.InterceptorRef;
import org.apache.struts2.convention.annotation.InterceptorRefs;
import org.apache.struts2.convention.annotation.Namespace;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.colortea.action.backstage.base.BaseTAction;
import com.colortea.action.backstage.base.DataCollectionTAction;
import com.colortea.action.backstage.utils.BaseTools;
import com.colortea.action.backstage.utils.enums.BaseEnums.GoodsSaleState;
import com.colortea.action.backstage.utils.statickey.FreeMarkervariable;
import com.colortea.action.backstage.utils.statickey.StaticKey;
import com.colortea.action.frontstage.utils.PageModel;
import com.colortea.action.frontstage.vo.RedisGoodsCategoryVo;
import com.colortea.entity.GoodsAttributeRpT;
import com.colortea.entity.GoodsAttributeT;
import com.colortea.entity.GoodsCategoryT;
import com.colortea.entity.GoodsT;
import com.colortea.redis.service.RedisBaseTService;
import com.colortea.service.GoodsAttributeRpTService;
import com.colortea.service.GoodsAttributeTService;
import com.colortea.service.GoodsCategoryTService;
import com.colortea.service.GoodsTService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

@ParentPackage("colortea")
@Namespace("/goods")
@InterceptorRefs({ @InterceptorRef("defaultStack") })
public class GoodsCategoryAction extends BaseTAction {

	private static String SALES = "sales";
	private static String MEMBERPRICE = "memberprice";
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	@Resource
	private DataCollectionTAction dataCollectionTAction;
	@Resource
	private GoodsCategoryTService goodsCategoryTService;
	@Resource
	private RedisBaseTService<RedisGoodsCategoryVo> redisBaseTService;
	@Resource
	private GoodsAttributeTService goodsAttributeTService;
	@Resource
	private GoodsTService goodsTService;
	@Resource
	private GoodsAttributeRpTService goodsAttributeRpTService;

	/**
	 * 获取商品分类页面信息 1，判定redis 2，获取商品分类对象 3，获取商品类型属性对象 4，放入redis 5,写入页面对象
	 * 
	 * @return
	 */
	@Action(value = "findGoodsCategory", results = { @Result(name = "success", type = "freemarker", location = "/WEB-INF/theme/default/shop/goodscategory.ftl") })
	public String findGoodsCategoryList() {
		this.dataCollectionTAction.putBaseInfoToContext();
		if (StringUtils.isBlank(this.getNavid())) {
			// 默认分类id
			this.setNavid("2014120700378");
		}
		RedisGoodsCategoryVo reCategoryVo = (RedisGoodsCategoryVo) redisBaseTService
				.get(FreeMarkervariable.GOODSCATEGORY + this.getNavid()
						+ this.getPage(), RedisGoodsCategoryVo.class);
		if (reCategoryVo == null) {
			reCategoryVo = new RedisGoodsCategoryVo();
			GoodsCategoryT gCategoryT = goodsCategoryTService.findByPK(
					GoodsCategoryT.class, this.getNavid());
			if (gCategoryT != null) {
				reCategoryVo.setGoodsCategoryT(gCategoryT);
				Criterion criterion = Restrictions.eq("goodsTypeId",
						gCategoryT.getGoodsTypeId());
				List<GoodsAttributeT> gAttributeTs = goodsAttributeTService
						.findByCriteria(GoodsAttributeT.class, criterion);
				reCategoryVo.setGoodsAttributeTs(gAttributeTs);
				int currentPage = page;
				int lineSize = rp;
				Map<String, String> params = new HashMap<>();
				params.put("navid", this.getNavid());
				params.put("goodsTypeId", gCategoryT.getGoodsTypeId());
				params.put("salestate", GoodsSaleState.SALE.getState());
				Criterion criterion2 = Restrictions.allEq(params);
				Order order = Order.desc("sort");
				List<GoodsT> goodsTs = this.goodsTService.findByCriteriaByPage(
						GoodsT.class, criterion2, order, currentPage, lineSize);
				reCategoryVo.setGoodsTs(goodsTs);
				int total = this.goodsTService.count(GoodsT.class, criterion2)
						.intValue();
				reCategoryVo.setTotal(total);
				redisBaseTService.put(
						FreeMarkervariable.GOODSCATEGORY + this.getNavid()
								+ this.getPage(), reCategoryVo,
						RedisGoodsCategoryVo.class, 10, TimeUnit.MINUTES);
			}
		}
		PageModel<GoodsT> pm = new PageModel<GoodsT>(page, rp,
				reCategoryVo.getGoodsTs(), reCategoryVo.getTotal());
		String action = BaseTools.getBasePath()
				+ "/goods/findGoodsCategory.action?navid=" + this.getNavid()
				+ "&page=" + page;
		ActionContext.getContext().put(FreeMarkervariable.ACTIONLINK, action);
		String sortsalesaction = BaseTools.getBasePath()
				+ "/goods/sortGoodsCategory.action?navid=" + this.getNavid()
				+ "&page=" + page + "&sorttype=sales";
		ActionContext.getContext().put(FreeMarkervariable.ACTIONSORTSALES,
				sortsalesaction);
		String sortmemberpriceaction = BaseTools.getBasePath()
				+ "/goods/sortGoodsCategory.action?navid=" + this.getNavid()
				+ "&page=" + page + "&sorttype=memberprice";
		ActionContext.getContext()
				.put(FreeMarkervariable.ACTIONSORTMEMBERPRICE,
						sortmemberpriceaction);

		ActionContext.getContext().put(FreeMarkervariable.GOODS, pm);
		ActionContext.getContext().put(FreeMarkervariable.TOTALGOODS,
				pm.getTotalRecord());
		ActionContext.getContext().put(FreeMarkervariable.TOTALPAGE,
				pm.getTotalpage());
		ActionContext.getContext().put(FreeMarkervariable.GOODSATTRS,
				reCategoryVo.getGoodsAttributeTs());
		ActionContext.getContext().put(FreeMarkervariable.GOODSCATEGORYPATH,
				reCategoryVo.getGoodsCategoryT());
		return SUCCESS;
	}

	/**
	 * 排序商品分类页面数据
	 * 
	 * @return
	 */
	@Action(value = "sortGoodsCategory", results = { @Result(name = "success", type = "freemarker", location = "/WEB-INF/theme/default/shop/goodscategory.ftl") })
	public String sortGoodsCategory() {
		this.dataCollectionTAction.putBaseInfoToContext();
		if (StringUtils.isBlank(this.getNavid())) {
			// 默认分类id
			this.setNavid("2014120700378");
		}
		RedisGoodsCategoryVo reCategoryVo = new RedisGoodsCategoryVo();
		if (StringUtils.equalsIgnoreCase(this.getSorttype(), SALES)) {
			reCategoryVo = sortBySales();
			String action = BaseTools.getBasePath()
					+ "/goods/findGoodsCategory.action?navid="
					+ this.getNavid() + "&page=" + page;
			ActionContext.getContext().put(FreeMarkervariable.ACTIONLINK,
					action);
			String sortsalesaction = BaseTools.getBasePath()
					+ "/goods/sortGoodsCategory.action?navid="
					+ this.getNavid() + "&page=" + page + "&sorttype=sales";
			ActionContext.getContext().put(FreeMarkervariable.ACTIONSORTSALES,
					sortsalesaction);
			String sortmemberpriceaction = BaseTools.getBasePath()
					+ "/goods/sortGoodsCategory.action?navid="
					+ this.getNavid() + "&page=" + page
					+ "&sorttype=memberprice";
			ActionContext.getContext().put(
					FreeMarkervariable.ACTIONSORTMEMBERPRICE,
					sortmemberpriceaction);
		}
		if (StringUtils.equalsIgnoreCase(this.getSorttype(), MEMBERPRICE)) {
			reCategoryVo = sortByMemberPrice();
			String action = BaseTools.getBasePath()
					+ "/goods/findGoodsCategory.action?navid="
					+ this.getNavid() + "&page=" + page;
			ActionContext.getContext().put(FreeMarkervariable.ACTIONLINK,
					action);
			String sortsalesaction = BaseTools.getBasePath()
					+ "/goods/sortGoodsCategory.action?navid="
					+ this.getNavid() + "&page=" + page + "&sorttype=sales";
			ActionContext.getContext().put(FreeMarkervariable.ACTIONSORTSALES,
					sortsalesaction);
			String sortmemberpriceaction = BaseTools.getBasePath()
					+ "/goods/sortGoodsCategory.action?navid="
					+ this.getNavid() + "&page=" + page
					+ "&sorttype=memberprice";
			ActionContext.getContext().put(
					FreeMarkervariable.ACTIONSORTMEMBERPRICE,
					sortmemberpriceaction);
		}
		PageModel<GoodsT> pm = new PageModel<GoodsT>(page, rp,
				reCategoryVo.getGoodsTs(), reCategoryVo.getTotal());
		ActionContext.getContext().put(FreeMarkervariable.GOODS, pm);
		ActionContext.getContext().put(FreeMarkervariable.TOTALGOODS,
				pm.getTotalRecord());
		ActionContext.getContext().put(FreeMarkervariable.TOTALPAGE,
				pm.getTotalpage());
		ActionContext.getContext().put(FreeMarkervariable.GOODSATTRS,
				reCategoryVo.getGoodsAttributeTs());
		ActionContext.getContext().put(FreeMarkervariable.GOODSCATEGORYPATH,
				reCategoryVo.getGoodsCategoryT());
		return SUCCESS;
	}

	private RedisGoodsCategoryVo sortByMemberPrice() {
		RedisGoodsCategoryVo reCategoryVo = (RedisGoodsCategoryVo) redisBaseTService
				.get(FreeMarkervariable.GOODSCATEGORY + this.getNavid()
						+ this.getPage() + MEMBERPRICE,
						RedisGoodsCategoryVo.class);
		if (reCategoryVo == null) {
			reCategoryVo = new RedisGoodsCategoryVo();
			GoodsCategoryT gCategoryT = goodsCategoryTService.findByPK(
					GoodsCategoryT.class, this.getNavid());
			if (gCategoryT != null) {
				reCategoryVo.setGoodsCategoryT(gCategoryT);
				Criterion criterion = Restrictions.eq("goodsTypeId",
						gCategoryT.getGoodsTypeId());
				List<GoodsAttributeT> gAttributeTs = goodsAttributeTService
						.findByCriteria(GoodsAttributeT.class, criterion);
				reCategoryVo.setGoodsAttributeTs(gAttributeTs);
				int currentPage = page;
				int lineSize = rp;
				Map<String, String> params = new HashMap<>();
				params.put("navid", this.getNavid());
				params.put("goodsTypeId", gCategoryT.getGoodsTypeId());
				params.put("salestate", GoodsSaleState.SALE.getState());
				Criterion criterion2 = Restrictions.allEq(params);
				Order order = Order.asc("memberprice");
				List<GoodsT> goodsTs = this.goodsTService.findByCriteriaByPage(
						GoodsT.class, criterion2, order, currentPage, lineSize);
				reCategoryVo.setGoodsTs(goodsTs);
				int total = this.goodsTService.count(GoodsT.class, criterion2)
						.intValue();
				reCategoryVo.setTotal(total);
				redisBaseTService.put(
						FreeMarkervariable.GOODSCATEGORY + this.getNavid()
								+ this.getPage() + MEMBERPRICE, reCategoryVo,
						RedisGoodsCategoryVo.class, 20, TimeUnit.MINUTES);
			}
		}
		return reCategoryVo;
	}

	private RedisGoodsCategoryVo sortBySales() {
		RedisGoodsCategoryVo reCategoryVo = (RedisGoodsCategoryVo) redisBaseTService
				.get(FreeMarkervariable.GOODSCATEGORY + this.getNavid()
						+ this.getPage() + SALES, RedisGoodsCategoryVo.class);
		if (reCategoryVo == null) {
			reCategoryVo = new RedisGoodsCategoryVo();
			GoodsCategoryT gCategoryT = goodsCategoryTService.findByPK(
					GoodsCategoryT.class, this.getNavid());
			if (gCategoryT != null) {
				reCategoryVo.setGoodsCategoryT(gCategoryT);
				Criterion criterion = Restrictions.eq("goodsTypeId",
						gCategoryT.getGoodsTypeId());
				List<GoodsAttributeT> gAttributeTs = goodsAttributeTService
						.findByCriteria(GoodsAttributeT.class, criterion);
				reCategoryVo.setGoodsAttributeTs(gAttributeTs);
				int currentPage = page;
				int lineSize = rp;
				Map<String, String> params = new HashMap<>();
				params.put("navid", this.getNavid());
				params.put("goodsTypeId", gCategoryT.getGoodsTypeId());
				params.put("salestate", GoodsSaleState.SALE.getState());
				Criterion criterion2 = Restrictions.allEq(params);
				Order order = Order.asc("sales");
				List<GoodsT> goodsTs = this.goodsTService.findByCriteriaByPage(
						GoodsT.class, criterion2, order, currentPage, lineSize);
				reCategoryVo.setGoodsTs(goodsTs);
				int total = this.goodsTService.count(GoodsT.class, criterion2)
						.intValue();
				reCategoryVo.setTotal(total);
				redisBaseTService.put(
						FreeMarkervariable.GOODSCATEGORY + this.getNavid()
								+ this.getPage() + SALES, reCategoryVo,
						RedisGoodsCategoryVo.class, 20, TimeUnit.MINUTES);
			}
		}
		return reCategoryVo;
	}

	/**
	 * 属性过滤商品
	 * 
	 * @return
	 */
	@Action(value = "fitlerGoodsByAttrs", results = { @Result(name = "success", type = "freemarker", location = "/WEB-INF/theme/default/shop/goodscategory.ftl") })
	public String fitlerGoodsByAttrs() {
		this.dataCollectionTAction.putBaseInfoToContext();
		if (StringUtils.isBlank(this.getNavid())) {
			// 默认分类id
			this.setNavid("2014120700378");
		}
		RedisGoodsCategoryVo reCategoryVo = (RedisGoodsCategoryVo) redisBaseTService
				.get(FreeMarkervariable.GOODSCATEGORY + this.getNavid()
						+ this.getPage() + this.getAttrs(),
						RedisGoodsCategoryVo.class);
		if (reCategoryVo == null) {
			reCategoryVo = new RedisGoodsCategoryVo();
			GoodsCategoryT gCategoryT = goodsCategoryTService.findByPK(
					GoodsCategoryT.class, this.getNavid());
			if (gCategoryT != null) {
				reCategoryVo.setGoodsCategoryT(gCategoryT);
				Criterion criterion = Restrictions.eq("goodsTypeId",
						gCategoryT.getGoodsTypeId());
				List<GoodsAttributeT> gAttributeTs = goodsAttributeTService
						.findByCriteria(GoodsAttributeT.class, criterion);
				reCategoryVo.setGoodsAttributeTs(gAttributeTs);
				int currentPage = page;
				int lineSize = rp;
				Map<String, String> params = new HashMap<>();
				params.put("navid", this.getNavid());
				params.put("goodsTypeId", gCategoryT.getGoodsTypeId());
				params.put("salestate", GoodsSaleState.SALE.getState());
				Criterion criterion2 = Restrictions.allEq(params);
				Order order = Order.asc("sort");
				List<GoodsT> goodsTs = this.goodsTService.findByCriteriaByPage(
						GoodsT.class, criterion2, order, currentPage, lineSize);
				String attrs[] = StringUtils.split(this.getAttrs(), ":");
				List<GoodsT> filterGoods = new ArrayList<GoodsT>();
				// 过滤属性
				String ss[] = null;
				for (String s : attrs) {
					if (!StringUtils.equalsIgnoreCase("全部", s)) {
						for (GoodsT g : goodsTs) {
							Criterion criterion3 = Restrictions.eq("goodsid",
									g.getGoodsid());
							List<GoodsAttributeRpT> gr = this.goodsAttributeRpTService
									.findByCriteria(GoodsAttributeRpT.class,
											criterion3);
							ss = StringUtils.split(s, StaticKey.SPLITDOT);
							for (GoodsAttributeRpT ga : gr) {
								if (StringUtils.equalsIgnoreCase(
										ga.getAttrval(), ss[0])) {
									filterGoods.add(g);
									break;
								}
							}
						}
					} else {
						filterGoods.addAll(goodsTs);
					}

				}
				reCategoryVo.setGoodsTs(filterGoods);
				reCategoryVo.setTotal(filterGoods.size());
				redisBaseTService.put(
						FreeMarkervariable.GOODSCATEGORY + this.getNavid()
								+ this.getPage() + this.getAttrs(),
						reCategoryVo, RedisGoodsCategoryVo.class, 20,
						TimeUnit.MINUTES);
			}
		}
		PageModel<GoodsT> pm = new PageModel<GoodsT>(page, rp,
				reCategoryVo.getGoodsTs(), reCategoryVo.getTotal());
		ActionContext.getContext().put(FreeMarkervariable.GOODS, pm);
		ActionContext.getContext().put(FreeMarkervariable.TOTALGOODS,
				pm.getTotalRecord());
		ActionContext.getContext().put(FreeMarkervariable.TOTALPAGE,
				pm.getTotalpage());
		ActionContext.getContext().put(FreeMarkervariable.GOODSATTRS,
				reCategoryVo.getGoodsAttributeTs());
		ActionContext.getContext().put(FreeMarkervariable.GOODSCATEGORYPATH,
				reCategoryVo.getGoodsCategoryT());
		String action = BaseTools.getBasePath()
				+ "/goods/findGoodsCategory.action?navid=" + this.getNavid()
				+ "&page=" + page;
		ActionContext.getContext().put(FreeMarkervariable.ACTIONLINK, action);
		String sortsalesaction = BaseTools.getBasePath()
				+ "/goods/sortGoodsCategory.action?navid=" + this.getNavid()
				+ "&page=" + page + "&sorttype=sales";
		ActionContext.getContext().put(FreeMarkervariable.ACTIONSORTSALES,
				sortsalesaction);
		String sortmemberpriceaction = BaseTools.getBasePath()
				+ "/goods/sortGoodsCategory.action?navid=" + this.getNavid()
				+ "&page=" + page + "&sorttype=memberprice";
		ActionContext.getContext()
				.put(FreeMarkervariable.ACTIONSORTMEMBERPRICE,
						sortmemberpriceaction);
		return SUCCESS;
	}

	/**
	 * 搜索商品
	 * 
	 * @return
	 */
	@Action(value = "searchGoods", results = { @Result(name = "success", type = "freemarker", location = "/WEB-INF/theme/default/shop/searchresult.ftl") })
	public String searchGoods() {
		this.dataCollectionTAction.putBaseInfoToContext();

		RedisGoodsCategoryVo reCategoryVo = (RedisGoodsCategoryVo) redisBaseTService
				.get(FreeMarkervariable.GOODSCATEGORY + this.getKey()
						+ this.getPage(), RedisGoodsCategoryVo.class);
		if (reCategoryVo == null) {
			reCategoryVo = new RedisGoodsCategoryVo();

			int currentPage = page;
			int lineSize = rp;
			Map<String, String> params = new HashMap<>();
			params.put("salestate", GoodsSaleState.SALE.getState());
			Criterion criterion2 = Restrictions.and(Restrictions.allEq(params))
					.add(Restrictions.like("goodsname", this.getKey(),
							MatchMode.ANYWHERE));
			Order order = Order.desc("sort");
			List<GoodsT> goodsTs = this.goodsTService.findByCriteriaByPage(
					GoodsT.class, criterion2, order, currentPage, lineSize);
			reCategoryVo.setGoodsTs(goodsTs);
			int total = this.goodsTService.count(GoodsT.class, criterion2)
					.intValue();
			reCategoryVo.setTotal(total);
			redisBaseTService.put(
					FreeMarkervariable.GOODSCATEGORY + this.getKey()
							+ this.getPage(), reCategoryVo,
					RedisGoodsCategoryVo.class, 20, TimeUnit.MINUTES);

		}
		PageModel<GoodsT> pm = new PageModel<GoodsT>(page, rp,
				reCategoryVo.getGoodsTs(), reCategoryVo.getTotal());
		String action = BaseTools.getBasePath()
				+ "/goods/searchGoods.action?key=" + this.getKey()
				+ "&page=" + page;
		ActionContext.getContext().put(FreeMarkervariable.ACTIONLINK, action);

		ActionContext.getContext().put(FreeMarkervariable.GOODS, pm);
		ActionContext.getContext().put(FreeMarkervariable.TOTALGOODS,
				pm.getTotalRecord());
		ActionContext.getContext().put(FreeMarkervariable.TOTALPAGE,
				pm.getTotalpage());
		ActionContext.getContext().put(FreeMarkervariable.GOODSATTRS,
				reCategoryVo.getGoodsAttributeTs());

		return SUCCESS;
	}

	/**
	 * 搜索关键字
	 */
	private String key;
	/**
	 * 过滤的属性对象
	 */
	private String attrs;

	/**
	 * 排序类型 sales or memberprice
	 */
	private String sorttype;

	/**
	 * 商品一级分类id
	 */
	private String navid;

	/**
	 * 当前页数
	 */
	private int page = 1;
	/**
	 * 每页展示数
	 */
	private int rp = 20;

	public String getKey() {
		return key;
	}

	public void setKey(String key) {
		this.key = key;
	}

	public String getAttrs() {
		return attrs;
	}

	public void setAttrs(String attrs) {
		this.attrs = attrs;
	}

	public String getSorttype() {
		return sorttype;
	}

	public void setSorttype(String sorttype) {
		this.sorttype = sorttype;
	}

	public String getNavid() {
		return navid;
	}

	public void setNavid(String navid) {
		this.navid = navid;
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		this.page = page;
	}

	public int getRp() {
		return rp;
	}

	public void setRp(int rp) {
		this.rp = rp;
	}

}
